/*
 * File:    FreemarkerRenderHook.java
 * Created: 14-Oct-2007
 * Version: $Id$
 *
 * COPYRIGHT (C) 2007, Bitgate Software, LLC.  All Rights Reserved.
 *
 * software@bitgatesoftware.com
 */

package com.bitgate.util.service.protocol.http.render.hook;

import static com.bitgate.util.debug.Debug.debug;
import static com.bitgate.util.debug.Debug.isDebugEnabled;

import java.io.IOException;
import java.io.StringWriter;
import java.util.HashMap;

import com.bitgate.util.service.protocol.http.HttpClientContext;
import com.bitgate.util.service.protocol.http.render.RenderHookException;
import com.bitgate.util.service.protocol.http.render.RenderHookInterface;
import com.bitgate.util.service.protocol.http.render.RenderHookResult;

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

/**
 * This class implements a rendering agent for Freemarker template pages.
 * 
 * @author kenji
 * @since 0.6.0
 */
public class FreemarkerRenderHook implements RenderHookInterface
{
	private Configuration cfg;
	
	/**
	 * No argument constructor.
	 */
	public FreemarkerRenderHook()
	{
		cfg = new Configuration();
		
		if (isDebugEnabled()) {
			debug("Freemarker Render Hook constructed.");
		}
	}
	
	/**
	 * Renders the specified filename with the given {@link HttpClientContext} object.
	 * 
	 * @param file The <code>String</code> containing the filename to render.
	 * @param hcContext The currently active <code>HttpClientContext</code> object.
	 * @return <code>byte[]</code> containing the result.
	 * @throws RenderHookException on any errors.
	 */
	public RenderHookResult renderPage(String file, final HttpClientContext hcContext) throws RenderHookException
	{
		Template t = null;
		RenderHookResult rhResult = new RenderHookResult();
		
		try {
			t = cfg.getTemplate(file);
		} catch(IOException e) {
			throw new RenderHookException("Unable to render page.", e);
		}
		
		StringWriter out = new StringWriter();
		HashMap<String, Object> vars = new HashMap<String, Object>();
		
		vars.put("http_vars", hcContext.getVariableStore());
		
		try {
			t.process(vars, out);
		} catch(TemplateException e) {
			throw new RenderHookException("Unable to process page.", e);
		} catch(IOException e) {
			throw new RenderHookException("Unable to load page.", e);
		}
		
		rhResult.setRenderedData(out.toString().getBytes());
		rhResult.setContentType("text/html");
		
		return rhResult;
	}
}